package com.apanal.qlife.common.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import com.apanal.qlife.common.cache.BaseCacheAspect;
import com.apanal.qlife.sys.model.User;

/**
 * 菜单缓存切面类
 * 
 * 
 * @author shuliangxing
 * 
 * @date 2015-9-30下午5:13:08
 */
@Component
@Aspect
public class ResourceMenuCacheAspect extends BaseCacheAspect {

	/**
	 * 设置菜单缓存名称
	 */
	public ResourceMenuCacheAspect() {
		setCacheName("sys-menuCache");
	}

	// 缓存key前缀
	private String menusKeyPrefix = "menus-";

	/**
	 * 目标类切点
	 */
	@Pointcut(value = "target(com.apanal.qlife.sys.service.ResourceService)")
	public void resourceServicePointcut() {
	}

	/**
	 * 增、删、改切点
	 */
	@Pointcut(value = "execution(* insert*(..)) || execution(* update*(..)) || execution(* delete*(..))")
	public void resourceCacheEvictAllPointcut() {
	}

	/**
	 * 查询切点
	 */
	@Pointcut(value = "execution(* findMenusForLevel(*)) && args(arg)", argNames = "arg")
	public void resourceMenuCacheablePointcut(User arg) {
	}

	/**
	 * 增、删、改前置通知
	 * 
	 * @throws Throwable
	 */
	@Before(value = "resourceServicePointcut() && resourceCacheEvictAllPointcut()")
	public void findResourceMenuEvictAdvice() throws Throwable {
		clear();
	}

	/**
	 * 查询环绕通知
	 * 
	 * @param pjp
	 * @param arg
	 * @return
	 * @throws Throwable
	 */
	@Around(value = "resourceServicePointcut() && resourceMenuCacheablePointcut(arg)", argNames = "pjp,arg")
	public Object findResourceMenuCacheableAdvice(ProceedingJoinPoint pjp,
			User arg) throws Throwable {
		User user = arg;

		String key = menusKey(user.getUseId());
		Object retVal = get(key);

		if (retVal != null) {
			log.debug(
					"cacheName:{}, method:findResourceMenuCacheableAdvice, hit key:{}",
					cacheName, key);
			return retVal;
		}
		log.debug(
				"cacheName:{}, method:findResourceMenuCacheableAdvice, miss key:{}",
				cacheName, key);

		retVal = pjp.proceed();

		put(key, retVal);

		return retVal;
	}

	/**
	 * 根据用户id移除缓存内容
	 * 
	 * @param userId
	 */
	public void evict(Long userId) {
		evict(menusKey(userId));
	}

	/**
	 * 根据用户id得到缓存key
	 * 
	 * @param userId
	 * @return
	 */
	private String menusKey(Long userId) {
		return this.menusKeyPrefix + userId;
	}

}
